
#ifndef CHANNEL_H
#define CHANNEL_H

#include "dpvs.h"

#include "typedefs.h"

#include <eq/eq.h>


namespace eqPc
{
    class FrameData;
    class InitData;

    /**
     * The rendering entity, updating a part of a Window.
     */
    class Channel : public eq::Channel
    {
    public:
        Channel( eq::Window* parent );

        bool stopRendering() const;

    protected:
        virtual ~Channel() {}

        virtual bool configInit( const eq::uint128_t& initID );
        virtual bool configExit();
        virtual void frameClear( const eq::uint128_t& frameID );
        virtual void frameDraw( const eq::uint128_t& frameID );
        virtual void frameAssemble( const eq::uint128_t& frameID );
        virtual void frameReadback( const eq::uint128_t& frameID );
        virtual void frameStart( const eq::uint128_t& frameID,
                                 const uint32_t frameNumber );
        virtual void frameFinish( const eq::uint128_t& frameID,
                                  const uint32_t frameNumber );
        virtual void frameViewStart( const eq::uint128_t& frameID );
        virtual void frameViewFinish( const eq::uint128_t& frameID );

        virtual bool useOrtho() const;
        virtual eq::Vector2f getJitter() const;

        virtual void notifyStopFrame( const uint32_t lastFrameNumber )
            { _frameRestart = lastFrameNumber + 1; }

    private:
        void _drawModel( const pc::PointCloud* model );
        void _drawOverlay();
        void _drawHelp();
        void _updateNearFar( const pc::BoundingSphere& boundingSphere );

        bool _isDone() const;

        void _initJitter();
        bool _initAccum();

        /** the subpixel for this step. */
        eq::Vector2i _getJitterStep() const;

        const FrameData& _getFrameData() const;
		const pc::PointCloud* _getModel();

		const pc::PointCloud* _model;
        eq::uint128_t _modelID;
        uint32_t _frameRestart;

        struct Accum
        {
            Accum() : buffer( 0 ), step( 0 ), stepsDone( 0 ), transfer( false )
                {}

            eq::util::Accum* buffer;
            int32_t step;
            uint32_t stepsDone;
            bool transfer;
        }
        _accum[ eq::NUM_EYES ];

        eq::PixelViewport _currentPVP;
    };
}

#endif // EQ_PLY_CHANNEL_H

